<script setup name="chooseImage">
import { ref } from "vue"
import ImageAside from "@/components/ImageAside.vue"
import ImageMain from "@/components/ImageMain.vue"
import { toast } from "@/composables/util"

// 接收外部传入
const props = defineProps({
  modelValue: [String, Array],
  limit: {
    type: Number,
    default: 1
  },
  preview: {
    type: Boolean,
    default: true
  }
})
// 响应外部修改内部数据
const emit = defineEmits(["update:modelValue"])
// 获取浏览器可视高度 或 Body 的可视高度
const windowHeight = ref(window.innerHeight || document.body.clientHeight)
// 减去头部高度、标签高度、内边距高度
const h = windowHeight.value - 64 - 44 - 186
// 左侧列表节点
const ImageAsideRef = ref(null)
// 图库内容节点
const ImageMainRef = ref(null)
// 显示/隐藏对话框
const showDialog = ref(false)
// 图片地址
let urls = []

// 回调
const callbackFunction = ref(null)
// 显示对话框
const open = (callback = null) => {
  callbackFunction.value = callback
  showDialog.value = true
}

// 关闭对话框
const close = () => (showDialog.value = false)

// 获取选中的图片
const handleChoose = e => (urls = e.map(v => v.url))

// 获取当选选中图片分类id
const handleAsideChange = id => ImageMainRef.value.loadData(id)

// 选中图片
const submit = () => {
  let value = []
  if (props.limit === 1) {
    value = urls[0]
  } else {
    value = props.preview ? [...props.modelValue, ...urls] : [...urls]
    if (value.length > props.limit) {
      let limit = props.preview ? props.limit - props.modelValue.length : props.limit
      return toast(`最多还能选择 ${limit} 张`, "error")
    }
  }
  if (value && props.preview) {
    emit("update:modelValue", value)
  }
  if (!props.preview && typeof callbackFunction.value === "function") {
    callbackFunction.value(value)
  }
  close()
}

// 删除头像
const handleDeleteUrls = () => {
  urls.length = 0
  emit("update:modelValue", urls[0])
}

// 多选删除
const removeImage = url =>
  emit(
    "update:modelValue",
    props.modelValue.filter(v => v !== url)
  )
// 导出方法
defineExpose({ open })
</script>

<template>
  <div v-if="modelValue && preview" class="avatar">
    <el-icon v-if="typeof modelValue === 'string'" class="close" @click="handleDeleteUrls"><Close /></el-icon>
    <el-image v-if="typeof modelValue === 'string'" :src="modelValue" fit="cover" />
    <div v-else class="avatar-image">
      <div class="avatar-image-box" v-for="(url, index) in modelValue" :key="index">
        <el-icon class="close" @click="removeImage(url)"><Close /></el-icon>
        <el-image :src="url" fit="cover" />
      </div>
      <div v-if="modelValue.length < limit" class="choose-image" @click="open">
        <el-icon size="25"><Plus /></el-icon>
      </div>
    </div>
  </div>
  <div v-if="preview && !modelValue" class="choose-image" @click="open">
    <el-icon size="25"><Plus /></el-icon>
  </div>
  <el-dialog class="choose-dialog" title="选择头像" v-model="showDialog" width="90%" :modal="false" :show-close="false" top="7.6vw" :close-on-click-modal="false">
    <el-container class="image-container" :style="{ height: `${h}px` }">
      <el-container>
        <ImageAside ref="ImageAsideRef" @change="handleAsideChange" />
        <ImageMain :limit="limit" ref="ImageMainRef" @choose="handleChoose" openChoose />
      </el-container>
    </el-container>
    <span class="footer">
      <el-button type="primary" @click="submit">确定</el-button>
      <el-button @click="close">取消</el-button>
    </span>
  </el-dialog>
</template>

<style lang="scss" scoped>
.avatar {
  position: relative;
  &-image {
    display: flex;
    flex-wrap: wrap;
    .choose-image {
      margin: 4px;
    }
    &-box {
      position: relative;
      margin: 4px;
      .close {
        position: absolute;
        top: 2px;
        right: 2px;
        z-index: 1;
        cursor: pointer;
        color: white;
      }
    }
  }
  .close {
    position: absolute;
    top: 2px;
    right: 2px;
    z-index: 1;
    cursor: pointer;
    color: white;
  }
}
.choose-image,
.el-image {
  width: 12vw;
  height: 12vw;
  border-radius: 4px;
  border: 1px solid var(--gray100);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: all 0.2s;
  &:hover {
    background: var(--main);
  }
  .el-icon {
    color: var(--gray100);
  }
}
.choose-dialog {
  padding: 0 !important;

  .image-container {
    background: var(--white);
    border-radius: 4px;
    &-header {
      border-bottom: 1px solid var(--border);
      display: flex;
      align-items: center;
    }
  }
  .footer {
    padding: 20px 0;
    display: flex;
    justify-content: center;
  }
}
</style>
